﻿using System;
using System.Drawing;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AEM.Utils;

namespace AEM.Data.BLL.Actions
{
    /// <summary>
    /// 图像处理器
    /// </summary>
    public static class ImageProcessor
    {
        static ImageProcessor()
        {
            ImportBackground = doImportBackground;
            ImportLogo = doImportLogo;
            LoadBackgroud = doLoadBackgroud;
            DeleteBackgroud = doDeleteBackgroud;
            LoadLogo = doLoadLogo;
            DeleteLogo = doDeleteLogo;
        }

        private static ImageBrush doLoadBackgroud(int screen)
        {
            Model.ClientConfig model = DAL.ClientConfig.Search();
            if (null != model)
            {
                if (!string.IsNullOrEmpty(model.SysBackgroud))
                {
                    string[] bg = model.SysBackgroud.Split(',');
                    if (bg.Length >= screen)
                        if (File.Exists(bg[screen - 1]))
                            return new ImageBrush(new BitmapImage(new Uri(bg[screen - 1])));
                }
            }
            return null;
        }

        private static bool doDeleteBackgroud(int screen)
        {
            Model.ClientConfig model = DAL.ClientConfig.Search();
            if (null != model)
            {
                if (!string.IsNullOrEmpty(model.SysBackgroud))
                {
                    string[] bg = model.SysBackgroud.Split(',');
                    if (bg.Length >= screen)
                    {
                        if (File.Exists(bg[screen - 1]))
                            try
                            {
                                File.Delete(bg[screen - 1]);
                            }
                            catch { }
                        bg[screen - 1] = "";
                        model.SysBackgroud = bg.Join(",");
                        DAL.ClientConfig.Update(model);
                        return true;
                    }
                }
            }
            return false;
        }

        private static ImageSource doLoadLogo()
        {
            Model.ClientConfig model = DAL.ClientConfig.Search();
            try
            {
                if (null != model)
                {
                    if (!string.IsNullOrEmpty(model.UserLogo))
                    {
                        if (File.Exists(model.UserLogo))
                            return new BitmapImage(new Uri(model.UserLogo));
                    }
                }
                return new BitmapImage(new Uri(Path.Combine(System.IO.Directory.GetCurrentDirectory(), "Logo.png")));
            }
            catch { return null; }
        }

        private static bool doDeleteLogo()
        {
            Model.ClientConfig model = DAL.ClientConfig.Search();
            if (null != model)
            {
                try
                {
                    if (File.Exists(model.UserLogo))
                        File.Delete(model.UserLogo);
                }
                catch { }
                model.UserLogo = "";
                DAL.ClientConfig.Update(model);
            }
            return false;
        }

        private static ImageBrush doImportBackground(int screen, string imgPath, double width, double height)
        {
            if (File.Exists(imgPath))
            {
                try
                {
                    string savePath = Path.Combine(Config.AEMConfigPath, DateTime.Now.ToString("yyyyMMddhhmmss") + Path.GetExtension(imgPath));
                    int percent = 40;
                    Single v = 0.006F * percent;
                    Single[][] matrix = {
                                        new Single[] { 1, 0, 0, 0, 0 }, 
                                        new Single[] { 0, 1, 0, 0, 0 }, 
                                        new Single[] { 0, 0, 1, 0, 0 }, 
                                        new Single[] { 0, 0, 0, 1, 0 }, 
                                        new Single[] { v, v, v, 0, 1 }
                                    };
                    System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(matrix);
                    System.Drawing.Imaging.ImageAttributes attr = new System.Drawing.Imaging.ImageAttributes();
                    attr.SetColorMatrix(cm);
                    //Image tmp
                    Image tmp = Image.FromFile(imgPath);
                    tmp = CreateThumbnail(tmp, width, height, false);//压缩图片
                    //提高图片质量
                    System.Drawing.Imaging.EncoderParameters encoderParams = new System.Drawing.Imaging.EncoderParameters();
                    long[] quality = new long[1];
                    quality[0] = 100;//图象质量
                    System.Drawing.Imaging.EncoderParameter encoderParam = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                    encoderParams.Param[0] = encoderParam;

                    System.Drawing.Imaging.ImageCodecInfo[] arrayICI = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
                    System.Drawing.Imaging.ImageCodecInfo jpegICI = null;
                    for (int x = 0; x < arrayICI.Length; x++)
                    {
                        if (arrayICI[x].FormatDescription.Equals("JPEG"))
                        {
                            jpegICI = arrayICI[x];
                            break;
                        }
                    }
                    Stream stream = new MemoryStream();
                    tmp.Save(stream, jpegICI, encoderParams);//存入流


                    Graphics g = Graphics.FromImage(tmp);

                    Rectangle destRect = new Rectangle(0, 0, tmp.Width, tmp.Height);
                    g.DrawImage(tmp, destRect, 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel, attr);

                    tmp.Save(savePath);

                    g.Dispose();

                    if (File.Exists(savePath))
                    {
                        Model.ClientConfig model = DAL.ClientConfig.Search();
                        if (null != model)
                        {
                            string[] bg = model.SysBackgroud.Split(',');
                            if (bg.Length < screen)
                            {
                                string[] tmpbg = bg;
                                bg = new string[screen];
                                Array.Copy(tmpbg, bg, tmpbg.Length);
                            }
                            bg[screen - 1] = savePath;
                            model.SysBackgroud = bg.Join(",");
                            DAL.ClientConfig.Update(model);
                        }
                        else
                        {
                            string[] bg = new string[screen];
                            bg[screen - 1] = savePath;
                            model = new Model.ClientConfig();
                            model.SysBackgroud = bg.Join(",");
                            DAL.ClientConfig.Add(model);
                        }
                        return new ImageBrush(new BitmapImage(new Uri(savePath)));
                    }
                }
                catch (Exception ex)
                {
                    AEM.Utils.Log.WriteError(ex.Message, ex);
                }
            }
            return null;
        }

        private static ImageSource doImportLogo(string imgPath, double width, double height)
        {
            if (File.Exists(imgPath))
            {
                try
                {
                    string savePath = Path.Combine(Config.AEMConfigPath, DateTime.Now.ToString("yyyyMMddhhmmss") + Path.GetExtension(imgPath));
                    Image tmp = Image.FromFile(imgPath);

                    tmp.Save(savePath);

                    if (File.Exists(savePath))
                    {
                        Model.ClientConfig model = DAL.ClientConfig.Search();
                        if (null != model)
                        {
                            model.UserLogo = savePath;
                            DAL.ClientConfig.Update(model);
                        }
                        else
                        {
                            model = new Model.ClientConfig();
                            model.UserLogo = savePath;
                            DAL.ClientConfig.Add(model);
                        }

                        return new BitmapImage(new Uri(savePath));
                    }
                }
                catch (Exception ex)
                {
                    AEM.Utils.Log.WriteError(ex.Message, ex);
                }
            }
            return null;
        }

        /// <summary>
        /// A better alternative to Image.GetThumbnail. Higher quality but slightly slower
        /// </summary>
        /// <param name="source"></param>
        /// <param name="thumbWi"></param>
        /// <param name="thumbHi"></param>
        /// <returns></returns>
        private static Image CreateThumbnail(Image source, double thumbWi, double thumbHi, bool maintainAspect)
        {
            // return the source image if it's smaller than the designated thumbnail
            if (source.Width < thumbWi && source.Height < thumbHi) return source;
            System.Drawing.Image ret = null;
            try
            {
                double wi, hi;

                wi = thumbWi;
                hi = thumbHi;

                if (maintainAspect)
                {
                    // maintain the aspect ratio despite the thumbnail size parameters
                    if (source.Width > source.Height)
                    {
                        wi = thumbWi;
                        hi = (int)(source.Height * ((decimal)thumbWi / source.Width));
                    }
                    else
                    {
                        hi = thumbHi;
                        wi = (int)(source.Width * ((decimal)thumbHi / source.Height));
                    }
                }

                // original code that creates lousy thumbnails
                // System.Drawing.Image ret = source.GetThumbnailImage(wi,hi,null,IntPtr.Zero);
                ret = new Bitmap((int)wi, (int)hi);
                using (Graphics g = Graphics.FromImage(ret))
                {
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.FillRectangle(System.Drawing.Brushes.White, 0, 0, (int)wi, (int)hi);
                    g.DrawImage(source, 0, 0, (int)wi, (int)hi);
                }
            }
            catch
            {
                ret = null;
            }

            return ret;
        }

        /// <summary>
        /// 导入背景,
        /// 参数一:第N屏
        /// 参数一:图片地址
        /// 参数二:宽
        /// 参数三:高
        /// 参数四:返回新的图片地址
        /// </summary>
        public static Func<int, string, double, double, ImageBrush> ImportBackground;
        public static Func<string, double, double, ImageSource> ImportLogo;
        //public static Func<ImageBrush> LoadBackgroud;
        public static Func<int, ImageBrush> LoadBackgroud;
        public static Func<int, bool> DeleteBackgroud;
        public static Func<ImageSource> LoadLogo;
        public static Func<bool> DeleteLogo;

    }
}
